package auth

import (
	"douhu_backend/internal/controller/common"
	"douhu_backend/internal/dao"
	"douhu_backend/internal/log"
	commonSvc "douhu_backend/internal/services/common"
	"strings"

	"github.com/kataras/iris/v12"
)

// AuthMiddleware 认证中间件
type AuthMiddleware struct {
	jwtService commonSvc.JWTService
	authDAO    dao.AuthDAO
}

// NewAuthMiddleware 创建认证中间件实例
func NewAuthMiddleware(jwtService commonSvc.JWTService, authDAO dao.AuthDAO) *AuthMiddleware {
	return &AuthMiddleware{
		jwtService: jwtService,
		authDAO:    authDAO,
	}
}

// RequireAuth 需要认证的中间件
func (m *AuthMiddleware) RequireAuth(ctx iris.Context) {
	// 获取Authorization header
	authHeader := ctx.Request().Header.Get("Authorization")
	if authHeader == "" {
		m.unauthorizedResponse(ctx, "缺少认证信息")
		return
	}

	// 检查Bearer前缀
	const bearerPrefix = "Bearer "
	if !strings.HasPrefix(authHeader, bearerPrefix) {
		m.unauthorizedResponse(ctx, "认证格式错误")
		return
	}

	// 提取token（去除 Bearer 前缀和前后空格）
	token := strings.TrimSpace(strings.TrimPrefix(authHeader, bearerPrefix))
	if token == "" {
		log.Warnf("empty token after trim, authHeader: %s", authHeader)
		m.unauthorizedResponse(ctx, "Token不能为空")
		return
	}

	// 验证token
	claims, err := m.jwtService.ParseToken(token)
	if err != nil {
		log.Errorf("parse jwt token failed: %v, token length: %d, authHeader: %s", err, len(token), authHeader)
		m.unauthorizedResponse(ctx, "Token无效")
		return
	}

	// 根据用户ID获取用户信息
	user, err := m.authDAO.GetUserByID(claims.UserID)
	if err != nil {
		log.Errorf("get user by id failed: %v", err)
		m.unauthorizedResponse(ctx, "用户不存在")
		return
	}

	// 检查用户状态
	if user.Status != 1 { // 1 表示正常状态
		m.unauthorizedResponse(ctx, "账户已被禁用")
		return
	}

	// 将用户信息存储到上下文中，供后续处理使用
	ctx.Values().Set("user", user)
	ctx.Values().Set("user_id", user.ID)
	ctx.Values().Set("phone", user.Phone)

	// 继续执行后续中间件或处理函数
	ctx.Next()
}

// OptionalAuth 可选认证的中间件（不强制要求登录）
func (m *AuthMiddleware) OptionalAuth(ctx iris.Context) {
	// 获取Authorization header
	authHeader := ctx.Request().Header.Get("Authorization")
	if authHeader == "" {
		// 没有认证信息，但不阻止请求继续
		ctx.Next()
		return
	}

	// 检查Bearer前缀
	const bearerPrefix = "Bearer "
	if !strings.HasPrefix(authHeader, bearerPrefix) {
		// 格式错误，但不阻止请求继续
		ctx.Next()
		return
	}

	// 提取token（去除 Bearer 前缀和前后空格）
	token := strings.TrimSpace(strings.TrimPrefix(authHeader, bearerPrefix))
	if token == "" {
		ctx.Next()
		return
	}

	// 验证token
	claims, err := m.jwtService.ParseToken(token)
	if err != nil {
		log.Warnf("parse jwt token failed in optional auth: %v, token length: %d", err, len(token))
		ctx.Next()
		return
	}

	// 根据用户ID获取用户信息
	user, err := m.authDAO.GetUserByID(claims.UserID)
	if err != nil {
		log.Warnf("get user by id failed in optional auth: %v", err)
		ctx.Next()
		return
	}

	// 检查用户状态
	if user.Status == 1 { // 只有正常状态的用户才设置上下文
		// 将用户信息存储到上下文中
		ctx.Values().Set("user", user)
		ctx.Values().Set("user_id", user.ID)
		ctx.Values().Set("phone", user.Phone)
	}

	// 继续执行后续中间件或处理函数
	ctx.Next()
}

// unauthorizedResponse 返回未授权响应
func (m *AuthMiddleware) unauthorizedResponse(ctx iris.Context, message string) {
	ctx.StopExecution()
	ctx.StatusCode(iris.StatusUnauthorized)
	ctx.JSON(common.RspProto{
		Code:      20015, // ErrNoAuth
		Message:   message,
		Data:      nil,
		Error:     message,
		RequestID: ctx.Request().Header.Get("X-Request-Id"),
	})
}